package study.itwill.team5.house;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import org.apache.log4j.Logger;

import study.itwill.common.DBHandler;
import study.itwill.common.Util;

public class HouseCity {

	// Logger 클래스의 인스턴스를 받아온다.
	static Logger logger = Logger.getLogger(HouseCity.class);
		
	private static final String TABLE = "House_city";
	
	/**
	 * 민박 도시 데이터를 신규로 저장 한 후 각 도시의 일련번호를 리턴한다.
	 * @param city_name		- 도시 이름
	 * @return  int			- 도시 일련번호
	 */
	public int addCity(String city_name) {
		logger.debug("=============== method start >> addHouse");
		logger.debug(" ------ [PARAMS INFO] ------");
		logger.debug("[PARAMS] city_name=" + city_name);
		
		int seq = -1;
		
		// SQL 인젝션 방어
		city_name = city_name.replace("'", "\'");
		
		// 트랜젝션에 대한 판단이 잘 서지 않는다면, 무조건 하면 된다.
		DBHandler.beginTrans();
		
		// INSERT 처리를 위한 구현
		String sql = "INSERT INTO house_city (city_name, reg_date, edit_date"
				+ ") VALUE ( "
				+ "'%s', '%s', '%s')";
		
		boolean result = DBHandler.execSql(sql, city_name, Util.getTime(), Util.getTime());
		
		//-----------------------------------------
		// 결과처리
		//-----------------------------------------
		if(result) {
			DBHandler.commit();
			seq =  DBHandler.getMax(TABLE, "seq", null);
			logger.debug("처리결과 >> " + seq + "번 도시 추가 성공");
		} else {
			DBHandler.rollback();
			logger.error("처리결과 >> 도시 추가 실패");
		}
		
		logger.debug("=============== method end >> addHouse");
		
		return seq;
	}
	
	/**
	 * 민박 도시 데이터를 수정하고 수정 성공 여부를 리턴한다.
	 * @param seq			- 도시 일련번호
	 * @param city_name		- 도시 이름
	 * @return	boolean		- 수정 성공 : true, 수정 실패 : false
	 */
	public boolean editCity(int seq, String city_name) {
		logger.debug("=============== method start >> editCity");
		logger.debug("[PARAMS] seq=" + seq);
		logger.debug("[PARAMS] city_name=" + city_name);
		// SQL 인젝션 방어
		city_name = city_name.replace("'", "\'");
	
		boolean result = false;

		DBHandler.beginTrans();
		String sql = "UPDATE house_city SET "
				+ "city_name='%s', edit_date='%s'"
				+ " WHERE seq = %d";

		result = DBHandler.execSql(sql, city_name, Util.getTime(), seq);

		if (result) {
			DBHandler.commit();
			logger.debug("처리결과 >> " + seq + "번 민박 수정 성공");
		} else {
			DBHandler.rollback();
			logger.debug("처리결과 >> 데이터 수정 실패");
		}
		
		logger.debug("=============== method end >> editCity");
		return result;
	}
	
	/**
	 * 민박 도시 데이터를 삭제하고 성공 여부를 리턴한다.
	 * @param house_city_seq- 도시 일련번호
	 * @return	boolean		- 삭제 성공 : true, 삭제 실패 : false
	 */
	public boolean deleteCity(int house_city_seq) {
		boolean result = false;
		logger.debug("=============== method start >> deleteCity");
		logger.debug("[PARAMS] house_city_seq=" + house_city_seq);
		
		// 이 데이터를 참조하는 다른 데이터들의 존재 여부 검사
		// SELECT COUNT(studno) FORM student WHERE profno = ?
		if (DBHandler.getCount("house", "seq", "house_city_seq=" + house_city_seq) > 0) {
			logger.error("참조 무결성 위반");
			return result;
		}
		
		DBHandler.beginTrans();
		
		String sql = "DELETE FROM house_city WHERE seq=%d";
		result = DBHandler.execSql(sql, house_city_seq);
		
		if(result) {
			DBHandler.commit();
			logger.debug("처리결과 >> " + house_city_seq + "번 도시 삭제 성공");
		} else {
			DBHandler.rollback();
			logger.debug("처리결과 >> 데이터 삭제 실패");
		}
		
		logger.debug("=============== method end >> deleteCity");
		return result;
	}
	
	/**
	 * 민박 도시 목록을 리턴한다.
	 * @param seq			- 도시 일련번호
	 * @return	item		- 도시 명 리턴
	 */
	public HouseCityItem selectCity (int seq) {
		logger.debug("========== method start >> selectCity");
		logger.debug("[PARAMS] seq=" + seq);
		
		HouseCityItem item = null;
		
		// 데이터 조회 
		String sql = "SELECT seq, city_name, reg_date, edit_date FROM house_city WHERE seq = %d";
		
		ResultSet rs = DBHandler.getResult(sql, seq);
		
		if(rs != null) {
			try {
				rs.next();
				
				// 1) ResultSet의 모든 데이터를 변수로 추출
				int n_seq = rs.getInt(1);
				String city_name = rs.getString(2);
				String reg_date = rs.getString(3);
				String edit_date = rs.getString(4);
				
				
				// 2) 추출된 값을 객체로 구성
				item = new HouseCityItem(n_seq, city_name, reg_date, edit_date);
				
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 3) 데이터 조회에 대한 메모리 반납
				try {
					rs.close();
				} catch (SQLException e) {
					rs = null;
				}
			}
			
			if(item == null) {
				logger.error("데이터 조회 실패");
			} else {
				logger.debug("데이터 조회 성공");
				logger.debug(item.toString());
			}
			
		}
		
		logger.debug("========== method end >> selectCity");
		
		return item;
	}
	
	/**
	 * 도시 목록 조회 기능
	 * @param choice			- 도시의 일련번호
	 * @return	item			- 도시의 정보 리턴
	 */
	public ArrayList<HouseCityItem> listCity(int choice) {
		logger.debug("========== method start >> listCity");
		
		ArrayList<HouseCityItem> list = null;
		
		
		/**
		 * 도시별 목록 보기를 위한 일련번호 
		 * 0 : 전체목록
		 * 1 : 베네치아
		 * 2 : 로마
		 */
		
		// 데이터 조회
		String sql = null;
		switch(choice) {
			case 0:
			sql = "SELECT seq, city_name, reg_date, edit_date FROM house_city";
				break;
			case 1:
				sql = "SELECT seq, city_name, reg_date, edit_date FROM house_city WHERE seq= %d";
				break;
			case 2: 
				sql = "SELECT seq, city_name, reg_date, edit_date FROM house_city WHERE seq= %d";
				break;
			default: 
				System.out.println("검색조건 선택이 올바르지 않습니다.");
				sql = "SELECT seq, city_name, reg_date, edit_date FROM house_city WHERE seq= -1";
				break;
		}
		
		ResultSet rs = DBHandler.getResult(sql);
		
		if(rs != null) {
			try {
				
				list = new ArrayList<HouseCityItem>();
				
				
				while (rs.next()) {
					// 1) ResultSet의 모든 데이터를 변수로 추출
					int seq = rs.getInt(1);
					String city_name = rs.getString(2);
					String reg_date = rs.getString(3);
					String edit_date = rs.getString(4);
					
					// 2) 추출된 값을 객체로 구성
					HouseCityItem item = new HouseCityItem(seq, city_name, reg_date, edit_date);
					
					// 3) ArrayList에 추가
					list.add(item);
				}
				
			} catch (SQLException e) {
				logger.error(e);
			} finally {
				// 4) 데이터 조회에 대한 메모리 반납
				try{
					rs.close();
				} catch (SQLException e){
					rs = null;
				}
				
			}
		}
		
		if(list == null) {
			logger.error("데이터 조회 실패");
		} else {
			logger.debug("데이터 조회 성공 >> " + list.size() + "건 조회됨");
		}
		
		logger.debug("========== method end >> listCity");
		
		return list;
	}
}
